#include "eventfd.hpp"
#include "header.h"
#include "logger.h"
namespace moqi
{


Eventfd::Eventfd(EventCallback &&cb):
_evenfd(createEventfd()),
_isRunning(false),
 _cb(std::move(cb))
{

}

Eventfd::~Eventfd()
{
    close(_evenfd);
}

void Eventfd::start()
{
    struct pollfd fdt;
    fdt.fd = _evenfd;
    fdt.events = POLLIN;

    _isRunning = true;

    while(_isRunning)
    {
        int nready = poll(&fdt, 1, 3000);
        if(nready == -1)
        {
            if(errno == EINTR)
            {
                continue;
            }
            LOG_ERROR("poll");
            break;
        }
        else if(nready == 0)
        {
            LOG_INFO("poll timeout");
        }
        else
        {
            handlReadEvent();
            if(_cb)
            {
                _cb();
            }
        }
    }

}

void Eventfd::stop()
{
    _isRunning = false;
}

void Eventfd::wakeup()
{
    uint64_t one = 1;
    int ret = write(_evenfd, &one, sizeof(one));
    if(ret != sizeof(one))
    {
        LOG_ERROR("wakeup");
    }
}

int Eventfd::createEventfd()
{
    int ret = ::eventfd(0, EFD_SEMAPHORE);
    if(ret < 0)
    {
        LOG_ERROR("eventfd");
    }
    return ret;
}

void Eventfd::handlReadEvent()
{
    uint64_t one = 0;
    int ret = read(_evenfd, &one, sizeof(one));
    if(ret != sizeof(one))
    {
        LOG_ERROR("read");
    }
    
}
}//end of namespace moqi
